home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 2000
/
MacHack 2000.toast
/
pc
/
The Hacks
/
Vertigo
/
Patches
/
Patches68K.c
next >
Wrap
C/C++ Source or Header
|
2000-06-23
|
12KB
|
524 lines
#define DISABLE_LOCAL_CALLTRACE 1 // Set to 1 to disable Call Traces for this file.
#define DISABLE_LOCAL_DEBUG 0 // Set to 1 to disable all debugging for this file.
#include "DebugUtils.h"
#include <Gestalt.h>
#include <Traps.h>
#include <Displays.h>
#include <QuickDraw.h>
#include "ContextUtils.h"
#include "Nub.h"
#include "PatchHarness.h"
#include "ProcInfo.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef pascal void (*CloseCPortProcPtr)(CGrafPtr port);
typedef pascal void (*ClosePortProcPtr)(GrafPtr port);
typedef pascal void (*OpenCPortProcPtr)(CGrafPtr port);
typedef pascal void (*OpenPortProcPtr)(GrafPtr port);
enum
{
_CleanUpApplication = 0xAAFB,
_SynchIdleTime = 0xABF7
};
pascal OSStatus main(PatchDesc **patchList);
static pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch);
static pascal void Remove(struct PatchDesc *desc);
static void CleanUpApplicationPatchHarness(void);
static void CleanUpApplicationSetTrapAddress(UniversalProcPtr addr);
static void CleanUpApplicationSetPatchAddress(UniversalProcPtr addr);
static pascal void CloseCPortPatchHarness(CGrafPtr port);
static pascal void ClosePortPatchHarness(GrafPtr port);
static pascal void CopyBitsPatchHarness(BitMap *srcBits,BitMap *dstBits,Rect *srcRect,Rect *dstRect,short mode,RgnHandle maskRgn);
static pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response);
static void GestaltSetSelectorResult(SInt32 value);
static pascal void OpenCPortPatchHarness(CGrafPtr port);
static pascal void OpenPortPatchHarness(GrafPtr port);
static void QuickTimeDispatchPatchHarness(void);
static void QuickTimeDispatchSetTrapAddress(UniversalProcPtr addr);
static void QuickTimeDispatchSetPatchAddress(UniversalProcPtr addr);
static void SynchIdleTimePatchHarness(void);
static void SynchIdleTimeSetTrapAddress(UniversalProcPtr addr);
static void SynchIdleTimeSetPatchAddress(UniversalProcPtr addr);
#ifdef __cplusplus
}
#endif
PatchDesc gCleanUpApplicationDesc;
PatchDesc gCloseCPortDesc;
CloseCPortProcPtr gCloseCPortTrap = NULL;
CloseCPortPatchPtr gCloseCPortPatch = NULL;
PatchDesc gClosePortDesc;
ClosePortProcPtr gClosePortTrap = NULL;
ClosePortPatchPtr gClosePortPatch = NULL;
PatchDesc gCopyBitsDesc;
CopyBitsProcPtr gCopyBitsTrap = NULL;
CopyBitsPatchPtr gCopyBitsPatch = NULL;
PatchDesc gGestaltSelectorDesc;
PatchDesc gOpenCPortDesc;
OpenCPortProcPtr gOpenCPortTrap = NULL;
OpenCPortPatchPtr gOpenCPortPatch = NULL;
PatchDesc gOpenPortDesc;
OpenPortProcPtr gOpenPortTrap = NULL;
OpenPortPatchPtr gOpenPortPatch = NULL;
PatchDesc gSynchIdleTimeDesc;
pascal OSStatus main(PatchDesc **patchList)
{
GlobalContext globals;
PatchDesc *head = *patchList;
ProcessSerialNumber psn;
OSStatus err;
// Install Gestalt selector.
gGestaltSelectorDesc.type = 'GSEL';
gGestaltSelectorDesc.install = Install;
gGestaltSelectorDesc.remove = Remove;
gGestaltSelectorDesc.next = head;
head = &gGestaltSelectorDesc;
err = NewGestalt(kNubSelector,GestaltSelectorHarness);
if (err != noErr)
{
OSType selector = kNubSelector;
dprintf(kDConPrefix "NewGestalt('%.4s') failed: %ld\n",&selector,err);
return err;
}
// Install _CleanUpApplication patch.
gCleanUpApplicationDesc.type = 'CApp';
gCleanUpApplicationDesc.install = Install;
gCleanUpApplicationDesc.remove = Remove;
gCleanUpApplicationDesc.next = head;
head = &gCleanUpApplicationDesc;
CleanUpApplicationSetTrapAddress(NGetTrapAddress(_CleanUpApplication,ToolTrap));
NSetTrapAddress((UniversalProcPtr)CleanUpApplicationPatchHarness,_CleanUpApplication,ToolTrap);
// Install _CloseCPort patch.
gCloseCPortDesc.type = 'ClCP';
gCloseCPortDesc.install = Install;
gCloseCPortDesc.remove = Remove;
gCloseCPortDesc.next = head;
head = &gCloseCPortDesc;
gCloseCPortTrap = (CloseCPortProcPtr)NGetTrapAddress(_CloseCPort,ToolTrap);
NSetTrapAddress((UniversalProcPtr)CloseCPortPatchHarness,_CloseCPort,ToolTrap);
// Install _ClosePort patch.
gClosePortDesc.type = 'CloP';
gClosePortDesc.install = Install;
gClosePortDesc.remove = Remove;
gClosePortDesc.next = head;
head = &gClosePortDesc;
gClosePortTrap = (ClosePortProcPtr)NGetTrapAddress(_ClosePort,ToolTrap);
NSetTrapAddress((UniversalProcPtr)ClosePortPatchHarness,_ClosePort,ToolTrap);
// Install _CopyBits patch.
gCopyBitsDesc.type = 'CBit';
gCopyBitsDesc.install = Install;
gCopyBitsDesc.remove = Remove;
gCopyBitsDesc.next = head;
head = &gCopyBitsDesc;
gCopyBitsTrap = (CopyBitsProcPtr)NGetTrapAddress(_CopyBits,ToolTrap);
NSetTrapAddress((UniversalProcPtr)CopyBitsPatchHarness,_CopyBits,ToolTrap);
// Install _OpenCPort patch.
gOpenCPortDesc.type = 'OpCP';
gOpenCPortDesc.install = Install;
gOpenCPortDesc.remove = Remove;
gOpenCPortDesc.next = head;
head = &gOpenCPortDesc;
gOpenCPortTrap = (OpenCPortProcPtr)NGetTrapAddress(_OpenCPort,ToolTrap);
NSetTrapAddress((UniversalProcPtr)OpenCPortPatchHarness,_OpenCPort,ToolTrap);
// Install _OpenPort patch.
gOpenPortDesc.type = 'OpnP';
gOpenPortDesc.install = Install;
gOpenPortDesc.remove = Remove;
gOpenPortDesc.next = head;
head = &gOpenPortDesc;
gOpenPortTrap = (OpenPortProcPtr)NGetTrapAddress(_OpenPort,ToolTrap);
NSetTrapAddress((UniversalProcPtr)OpenPortPatchHarness,_OpenPort,ToolTrap);
// Install _SynchIdleTime patch.
gSynchIdleTimeDesc.type = 'IDLE';
gSynchIdleTimeDesc.install = Install;
gSynchIdleTimeDesc.remove = Remove;
gSynchIdleTimeDesc.next = head;
head = &gSynchIdleTimeDesc;
QuickTimeDispatchSetTrapAddress(NGetTrapAddress(0xAAAA,ToolTrap));
NSetTrapAddress((UniversalProcPtr)QuickTimeDispatchPatchHarness,0xAAAA,ToolTrap);
//SynchIdleTimeSetTrapAddress(NGetTrapAddress(_SynchIdleTime,ToolTrap));
//NSetTrapAddress((UniversalProcPtr)SynchIdleTimePatchHarness,_SynchIdleTime,ToolTrap);
// Set patch list.
*patchList = head;
return noErr;
}
pascal void Install(struct PatchDesc *desc,UniversalProcPtr patch)
{
GlobalContext globals;
switch(desc->type)
{
case 'CApp':
CleanUpApplicationSetPatchAddress(patch);
break;
case 'ClCP':
gCloseCPortPatch = (CloseCPortPatchPtr)patch;
break;
case 'CloP':
gClosePortPatch = (ClosePortPatchPtr)patch;
break;
case 'CBit':
gCopyBitsPatch = (CopyBitsPatchPtr)patch;
break;
case 'OpCP':
gOpenCPortPatch = (OpenCPortPatchPtr)patch;
break;
case 'OpnP':
gOpenPortPatch = (OpenPortPatchPtr)patch;
break;
case 'GSEL':
// Remove Gestalt selector result.
GestaltSetSelectorResult((SInt32)patch);
break;
case 'IDLE':
QuickTimeDispatchSetPatchAddress((UniversalProcPtr)patch);
//SynchIdleTimeSetPatchAddress((UniversalProcPtr)patch);
break;
default:
dprintf(kDConPrefix "Install: patch '%.4s' not found\n",&desc->type);
break;
}
}
pascal void Remove(struct PatchDesc *desc)
{
GlobalContext globals;
switch(desc->type)
{
case 'CApp':
CleanUpApplicationSetPatchAddress(NULL);
break;
case 'ClCP':
gCloseCPortPatch = NULL;
break;
case 'CloP':
gClosePortPatch = NULL;
break;
case 'CBit':
gCopyBitsPatch = NULL;
break;
case 'OpCP':
gOpenCPortPatch = NULL;
break;
case 'OpnP':
gOpenPortPatch = NULL;
break;
case 'GSEL':
// Remove Gestalt selector result.
GestaltSetSelectorResult((SInt32)0);
break;
case 'IDLE':
QuickTimeDispatchSetPatchAddress(NULL);
//SynchIdleTimeSetPatchAddress(NULL);
break;
default:
dprintf(kDConPrefix "Remove: patch '%.4s' not found\n",&desc->type);
break;
}
}
#if 0
#pragma mark -
#endif
asm void CleanUpApplicationPatchHarness(void)
{
PEA @1
MOVE.L @TrapAddressStorage,-(SP) // Put address of trap into A1.
RTS
@1: MOVEM.L D0-D2/A0-A1,-(A7) // Save CPU state on stack.
MOVEA.L @PatchAddressStorage,A0 // Put address of patch into A0.
CMPA.W #0x0000,A0 // Compare address of patch to NULL.
BEQ.S @CallRealTrap // Goto @CallRealTrap if was NULL.
JSR (A0) // Call patch code.
@CallRealTrap:
MOVEM.L (A7)+,D0-D2/A0-A1 // Restore CPU state from stack.
RTS // Return to real trap.
entry static CleanUpApplicationSetTrapAddress
LEA @TrapAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
entry static CleanUpApplicationSetPatchAddress
LEA @PatchAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
@TrapAddressStorage:
DC.L 0x00000000 // Storage for trap address.
@PatchAddressStorage:
DC.L 0x00000000 // Storage for patch address.
}
pascal void CloseCPortPatchHarness(CGrafPtr port)
{
CloseCPortProcPtr closeCPortTrap;
{
GlobalContext globals;
closeCPortTrap = gCloseCPortTrap;
if (gCloseCPortPatch != NULL)
CallCloseCPortPatch(gCloseCPortPatch,port);
}
closeCPortTrap(port);
}
pascal void ClosePortPatchHarness(GrafPtr port)
{
ClosePortProcPtr closePortTrap;
{
GlobalContext globals;
closePortTrap = gClosePortTrap;
if (gClosePortPatch != NULL)
CallClosePortPatch(gClosePortPatch,port);
}
closePortTrap(port);
}
pascal void CopyBitsPatchHarness(BitMap *srcBits,BitMap *dstBits,Rect *srcRect,Rect *dstRect,short mode,RgnHandle maskRgn)
{
CopyBitsProcPtr copyBitsTrap;
CopyBitsPatchPtr copyBitsPatch;
{
GlobalContext globals;
copyBitsTrap = gCopyBitsTrap;
copyBitsPatch = gCopyBitsPatch;
}
if (copyBitsPatch == NULL)
copyBitsTrap(srcBits,dstBits,srcRect,dstRect,mode,maskRgn);
else
copyBitsPatch(srcBits,dstBits,srcRect,dstRect,mode,maskRgn,copyBitsTrap);
}
asm pascal OSErr GestaltSelectorHarness(OSType selector,SInt32 *response)
{
MOVEA.L 4(SP),A0 // Move response into A0.
MOVE.L @ResultStorage,(A0) // Move *ResultStorage into *response.
CLR.W 12(SP) // Set the return value to no error.
RTD #8 // Clean up pascal stack frame and return.
entry static GestaltSetSelectorResult
LEA @ResultStorage,A0
MOVE.L 4(SP),(A0)
RTS
@ResultStorage:
DC.L 0x00000000 // 4 Byte return value.
}
pascal void OpenCPortPatchHarness(CGrafPtr port)
{
OpenCPortProcPtr openCPortTrap;
{
GlobalContext globals;
openCPortTrap = gOpenCPortTrap;
}
openCPortTrap(port);
{
GlobalContext globals;
if (gOpenCPortPatch != NULL)
CallOpenCPortPatch(gOpenCPortPatch,port);
}
}
pascal void OpenPortPatchHarness(GrafPtr port)
{
OpenPortProcPtr openPortTrap;
{
GlobalContext globals;
openPortTrap = gOpenPortTrap;
}
openPortTrap(port);
{
GlobalContext globals;
if (gOpenPortPatch != NULL)
CallOpenPortPatch(gOpenPortPatch,port);
}
}
asm void QuickTimeDispatchPatchHarness(void)
{
MOVEA.L @TrapAddressStorage,A1 // Put address of trap into A1.
MOVEA.L @PatchAddressStorage,A0 // Put address of patch into A0.
CMPA.W #0x0000,A0 // Compare address of patch to NULL.
BEQ.S @CallRealTrap // Goto @CallRealTrap if was NULL.
CMPI.W #0x82F0,D0
BNE.S @CallRealTrap
MOVEM.L D0-D7/A1-A6,-(A7) // Save CPU state on stack.
JSR (A0) // Call patch code.
MOVEM.L (A7)+,D0-D7/A1-A6 // Restore CPU state from stack.
@CallRealTrap:
JMP (A1) // Directly jump to real trap.
entry static QuickTimeDispatchSetTrapAddress
LEA @TrapAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
entry static QuickTimeDispatchSetPatchAddress
LEA @PatchAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
@TrapAddressStorage:
DC.L 0x00000000 // Storage for trap address.
@PatchAddressStorage:
DC.L 0x00000000 // Storage for patch address.
}
asm void SynchIdleTimePatchHarness(void)
{
MOVEA.L @TrapAddressStorage,A1 // Put address of trap into A1.
MOVEA.L @PatchAddressStorage,A0 // Put address of patch into A0.
CMPA.W #0x0000,A0 // Compare address of patch to NULL.
BEQ.S @CallRealTrap // Goto @CallRealTrap if was NULL.
MOVEM.L D3-D7/A1-A6,-(A7) // Save CPU state on stack.
JSR (A0) // Call patch code.
MOVEM.L (A7)+,D3-D7/A1-A6 // Restore CPU state from stack.
@CallRealTrap:
JMP (A1) // Directly jump to real trap.
entry static SynchIdleTimeSetTrapAddress
LEA @TrapAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
entry static SynchIdleTimeSetPatchAddress
LEA @PatchAddressStorage,A0
MOVE.L 4(SP),(A0)
RTS
@TrapAddressStorage:
DC.L 0x00000000 // Storage for trap address.
@PatchAddressStorage:
DC.L 0x00000000 // Storage for patch address.
}